home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The X-Philes (2nd Revision)
/
The X-Philes Number 1 (1995).iso
/
xphiles
/
hp48_2
/
chasm01.sha
/
lex.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-23
|
5KB
|
397 lines
/*
* lex.c - lexical analyzer
*
* @(#)lex.c 1.1 91/04/10
*
* Copyright (c) 1991 Steve Scherf
*
* Author: Steve Scherf
* Date: Wed Apr 10 22:53:11 PDT 1991
*
*/
#include <stdio.h>
#include <ctype.h>
#include "chasm.h"
extern int yylval;
char *insttab[] = {
"add", "and", "bcd", "cld", "data", "def", "dmp", "dsp", "ink",
"jmp", "jof", "jsr", "mem", "mov", "or", "res", "ret", "rnd",
"sar", "seq", "shl", "shr", "sip", "sne", "snp", "ssc", "sub", "xor"
};
int ninst = sizeof(insttab) / sizeof(char *);
char *vartab[] = {
"dtimer",
"stimer",
"i"
};
int nvar = sizeof(vartab) / sizeof(char *);
char getch();
char getcconst();
char getslash();
char getslashval();
char getqchar();
char *gettoken();
int getinstr();
int getstr();
int getconst();
int getreg();
int gethex();
int getoct();
int getdec();
int getvar();
/* lexical analyzer */
yylex()
{
unsigned int x;
register int i;
register char *s;
char l[512], lbl[512], c;
s = gettoken();
if(!s)
return 0;
if(*s == '"')
if((yylval = (int)getstr()) != 0)
return STRING;
else
return 1;
if(*s == '\'')
if((yylval = getcconst()) != -1)
return CONST;
else
return 1;
if(isctok(*s))
return *s;
if((i = getinstr(s)) >= 0)
return(i + IBASE);
if((yylval = getvar(s)) != -1)
return VAR;
if((yylval = getreg(s)) != -1)
return REG;
if((yylval = getconst(s)) != -1)
return CONST;
if(islabel(s) != 0) {
strcpy(lbl, s);
yylval = (int)lbl;
return LABEL;
}
return 1;
}
/* read one token from input */
char *
gettoken()
{
register char *p;
static char l[512];
static char ctok = 0;
if(ctok) {
l[0] = ctok;
l[1] = '\0';
ctok = 0;
return l;
}
p = l;
while((*p = getch()) != EOF && isspace(*p) && !isctok(*p))
continue;
if(*p == EOF)
return 0;
if(isctok(*p)) {
*(++p) = '\0';
return l;
}
p++;
while((*p = getch()) != EOF && !isspace(*p) && *p != ',' && *p != ':' &&
p < l + sizeof(l) - 1)
p++;
if(isctok(*p))
ctok = *p;
*p = '\0';
return l;
}
/* get one character, ignoring comments */
char
getch()
{
register char c;
if((c = getc(ifp)) != ';' && c != '/')
return c;
while(getc(ifp) != '\n')
continue;
return '\n';
}
/* return true if c is a one character token */
isctok(c)
register c;
{
if(c == ',' || c == '\n' || c == '"' || c == '\'' || c == ':')
return 1;
return 0;
}
/* get a single-quoted character constant from input */
char
getcconst()
{
char c, d;
c = getc(ifp);
if(c == '\\') {
if((c = getslash()) == EOF)
return -1;
}
else
if(c == '\n') {
ungetc(c, ifp);
return -1;
}
if((d = getc(ifp)) == '\n')
ungetc(d, ifp);
else
if(d == '\'')
return c;
return -1;
}
/* get string of characters from input */
int
getstr()
{
register char *p;
static char l[512];
p = l;
while((*p = getc(ifp)) != EOF && *p != '\n' && *p != '"' &&
p < l + sizeof(l) - 1) {
if(*p == '\\' && (*p = getslash()) == EOF)
return 0;
p++;
}
if(*p == '\n')
ungetc('\n', ifp);
if(*p != '"')
return 0;
*p = '\0';
return((int)l);
}
/* get a backslash-escaped character from input */
char
getslash()
{
register char c;
if((c = getc(ifp)) == '\n') {
ungetc(c, ifp);
return EOF;
}
switch(c) {
case 'b':
return '\b';
case 'n':
return '\n';
case 'r':
return '\r';
case 't':
return '\t';
case '0':
return '\0';
case EOF:
return EOF;
default:
return c;
}
}
/* return true if s is an alphanumeric label */
islabel(s)
char *s;
{
if(isdigit(*s))
return 0;
while(*s && (isalnum(*s) || *s == '_'))
s++;
return(*s == '\0');
}
/* if s is an instruction, return index in table */
int
getinstr(s)
char *s;
{
register char *p1, *p2;
register int i;
for(i = 0; i < ninst; i++) {
for(p1 = s, p2 = insttab[i]; *p1 && *p2; p1++, p2++)
if(*p1 != *p2 && *p1 != toupper(*p2))
break;
if(!*p1 && !*p2)
return i;
}
return -1;
}
/* if s is a register, return its number */
int
getreg(s)
register char *s;
{
register int x;
if((s[0] == 'V' || s[0] == 'v') && s[2] == '\0') {
x = gethex(s+1);
if(x >= 0x0 && x <= 0xF)
return x;
}
return -1;
}
/* convert s to an integer of the appropriate base */
int
getconst(s)
register char *s;
{
if(s[0] == '0')
if(s[1] == 'x' || s[1] == 'X')
return(gethex(s+2));
else
return(getoct(s+1));
return(getdec(s));
}
/* convert s to a hex integer */
int
gethex(s)
register char *s;
{
register int n, l;
for(n = 0; *s; s++) {
if(!isxdigit(*s))
return -1;
if(isdigit(*s))
n = (n << 4) + *s - '0';
else {
if(isupper(*s))
*s = tolower(*s);
n = (n << 4) + *s - 'a' + 10;
}
}
return n;
}
/* convert s to an octal integer */
int
getoct(s)
register char *s;
{
register int n;
for(n = 0; *s; s++) {
if(!isdigit(*s) || *s > '7')
return -1;
n = (n << 3) + *s - '0';
}
return n;
}
/* convert s to a decimal integer */
int
getdec(s)
register char *s;
{
register int n;
for(n = 0; *s; s++) {
if(!isdigit(*s))
return -1;
n = (n * 10) + *s - '0';
}
return n;
}
/* if s is a special variable, return its index */
int
getvar(s)
char *s;
{
register char *p1, *p2;
register int i;
for(i = 0; i < nvar; i++) {
for(p1 = s, p2 = vartab[i]; *p1 && *p2; p1++, p2++)
if(*p1 != *p2 && *p1 != toupper(*p2))
break;
if(!*p1 && !*p2)
return i;
}
return -1;
}